home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / progsrc / thesrc20 / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-26  |  50.1 KB  |  1,486 lines

  1. /***********************************************************************/
  2. /* FILE.C - File and view related functions.                           */
  3. /***********************************************************************/
  4. /*
  5.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  6.  * Copyright (C) 1991-1995 Mark Hessling
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License as
  10.  * published by the Free Software Foundation; either version 2 of
  11.  * the License, or any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16.  * General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to:
  20.  *
  21.  *    The Free Software Foundation, Inc.
  22.  *    675 Mass Ave,
  23.  *    Cambridge, MA 02139 USA.
  24.  *
  25.  *
  26.  * If you make modifications to this software that you feel increases
  27.  * it usefulness for the rest of the community, please email the
  28.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  29.  * This software is going to be maintained and enhanced as deemed
  30.  * necessary by the community.
  31.  *
  32.  * Mark Hessling                     email: M.Hessling@gu.edu.au
  33.  * 36 David Road                     Phone: +61 7 849 7731
  34.  * Holland Park                      Fax:   +61 7 875 5314
  35.  * QLD 4121
  36.  * Australia
  37.  */
  38.  
  39. /*
  40. $Id: file.c 2.0 1995/01/26 16:31:04 MH Release MH $
  41. */
  42.  
  43. #include <stdio.h>
  44. #include <errno.h>
  45.  
  46. #include "the.h"
  47. #include "directry.h"
  48. #include "proto.h"
  49.  
  50. #if defined(DOS) || defined(OS2)
  51. #include <io.h>
  52. #endif
  53.  
  54. /****************** needs to be fixed *************/
  55. #ifdef GO32
  56. #define stricmp strcasecmp
  57. #endif
  58.  
  59. /*#define TRACE*/
  60. /***********************************************************************/
  61. #ifdef PROTO
  62. short get_file(CHARTYPE *filename)
  63. #else
  64. short get_file(filename)
  65. CHARTYPE *filename;
  66. #endif
  67. /***********************************************************************/
  68. {
  69. /*-------------------------- external data ----------------------------*/
  70.  extern struct stat stat_buf;
  71.  extern bool in_profile;
  72.  extern CHARTYPE file_disposition;
  73.  extern CHARTYPE *rexxoutname;
  74.  extern CHARTYPE number_of_files;
  75.  extern CHARTYPE rexx_filename[10];
  76.  extern CHARTYPE rexx_pathname[MAX_FILE_NAME+1];
  77.  extern CHARTYPE dir_filename[10];
  78.  extern CHARTYPE dir_pathname[MAX_FILE_NAME+1];
  79.  extern CHARTYPE sp_path[MAX_FILE_NAME+1];
  80.  extern CHARTYPE sp_fname[MAX_FILE_NAME+1];
  81. /*--------------------------- local data ------------------------------*/
  82.  LINE *curr=NULL;
  83.  CHARTYPE work_filename[MAX_FILE_NAME+1] ;
  84.  VIEW_DETAILS *save_current_view=NULL,*found_file=NULL;
  85.  short rc=RC_OK;
  86.  bool directory_file=FALSE;
  87.  FILE_DETAILS *save_current_file=NULL;
  88. /*--------------------------- processing ------------------------------*/
  89. #ifdef TRACE
  90.  trace_function("file.c:    get_file");
  91. #endif
  92. /*---------------------------------------------------------------------*/
  93. /* Split the filename supplied into directory and filename parts.      */
  94. /* This is done before allocating a new current_file number.           */
  95. /*---------------------------------------------------------------------*/
  96.  
  97.  if ((rc = splitpath(filename)) != RC_OK)
  98.    {
  99.     display_error(10,filename,FALSE);
  100. #ifdef TRACE
  101.     trace_return();
  102. #endif
  103.     return(rc);
  104.    }
  105. /*---------------------------------------------------------------------*/
  106. /* If the filename portion of the splithpath is empty, then we are     */
  107. /* editing a directory. So create the new file with the appropriate OS*/
  108. /* command and set the filename to DIR.DIR.                            */
  109. /*---------------------------------------------------------------------*/
  110.  if (strcmp(sp_fname,"") == 0)
  111.    {
  112.     if ((rc = read_directory()) != RC_OK)
  113.        {
  114. #ifdef TRACE
  115.         trace_return();
  116. #endif
  117.         return(rc);
  118.        }
  119.     strcpy(sp_path,dir_pathname);
  120.     strcpy(sp_fname,dir_filename);
  121.    }
  122. /*---------------------------------------------------------------------*/
  123. /* If this is the first file to be edited, don't check to see if the  */
  124. /* file is already in the ring. Obvious hey!                           */
  125. /*---------------------------------------------------------------------*/
  126.  if (CURRENT_VIEW == (VIEW_DETAILS *)NULL)     /* no files in ring yet */
  127.    {
  128.     if ((rc = defaults_for_first_file()) != RC_OK)
  129.       {
  130. #ifdef TRACE
  131.        trace_return();
  132. #endif
  133.        return(rc);
  134.       }
  135.    }
  136.  else
  137.    {
  138. /*---------------------------------------------------------------------*/
  139. /* Here we should check if we already have the file to be edited in   */
  140. /* the ring. If the file is there and it is DIR.DIR, QQUIT out of it   */
  141. /* otherwise set the current pointer to it and exit.                   */
  142. /* Same applies to REXX output file.                                   */
  143. /*---------------------------------------------------------------------*/
  144.     save_current_view = CURRENT_VIEW;
  145.     if ((found_file = find_file(sp_path,sp_fname)) != (VIEW_DETAILS *)NULL)
  146.       {
  147.        CURRENT_VIEW = found_file;
  148. /*       if (CURRENT_FILE->pseudo_file == PSEUDO_DIR
  149.        ||  CURRENT_FILE->pseudo_file == PSEUDO_REXX)*/
  150.        if ((strcmp(CURRENT_FILE->fname,dir_filename) == 0
  151.        &&   strcmp(CURRENT_FILE->fpath,dir_pathname) == 0)
  152.        || (strcmp(CURRENT_FILE->fname,rexx_filename) == 0
  153.        &&  strcmp(CURRENT_FILE->fpath,rexx_pathname) == 0))
  154.          {
  155.           Qquit("");
  156.           if (CURRENT_VIEW == (VIEW_DETAILS *)NULL)
  157.              rc = defaults_for_first_file();
  158.           else
  159.             {
  160.              save_current_file = CURRENT_FILE;
  161.              rc = defaults_for_other_files(FALSE);
  162.             }
  163.           if (rc != RC_OK)
  164.             {
  165. #ifdef TRACE
  166.              trace_return();
  167. #endif
  168.              return(rc);
  169.             }
  170.          }
  171.        else
  172.           {
  173. #ifdef TRACE
  174.            trace_return();
  175. #endif
  176.            return(RC_OK);
  177.           }
  178.       }
  179.     else
  180.       {
  181.        CURRENT_VIEW = save_current_view;
  182.        save_current_file = CURRENT_FILE;
  183.        if ((rc = defaults_for_other_files(FALSE)) != RC_OK)
  184.          {
  185. #ifdef TRACE
  186.           trace_return();
  187. #endif
  188.           return(rc);
  189.          }
  190.       }
  191.     }
  192. /*---------------------------------------------------------------------*/
  193. /* Increment the number of files in storage here, so that if there are */
  194. /* any problems with reading the file, free_file_memory() function can */
  195. /* correctly decrement the number of files.                            */
  196. /*---------------------------------------------------------------------*/
  197.  number_of_files++;
  198. /*---------------------------------------------------------------------*/
  199. /* Allocate memory to file pointer.                                    */
  200. /*---------------------------------------------------------------------*/
  201.  if ((CURRENT_FILE = (FILE_DETAILS *)(*the_malloc)(sizeof(FILE_DETAILS))) == NULL)
  202.    {
  203.     free_view_memory();
  204.     display_error(30,(CHARTYPE *)"",FALSE);
  205. #ifdef TRACE
  206.     trace_return();
  207. #endif
  208.     return(RC_OUT_OF_MEMORY);
  209.    }
  210. /*---------------------------------------------------------------------*/
  211. /* Allocate space for file's colour attributes...                      */
  212. /*---------------------------------------------------------------------*/
  213.  if ((CURRENT_FILE->attr = (COLOUR_ATTR *)(*the_malloc)(ATTR_MAX*sizeof(COLOUR_ATTR))) == NULL)
  214.    {
  215.     display_error(30,(CHARTYPE *)"",FALSE);
  216. #ifdef TRACE
  217.     trace_return();
  218. #endif
  219.     return(RC_OUT_OF_MEMORY);
  220.    }
  221.  memset(CURRENT_FILE->attr,0,ATTR_MAX*sizeof(COLOUR_ATTR));
  222. /*---------------------------------------------------------------------*/
  223. /* Set up default file attributes.                                     */
  224. /*---------------------------------------------------------------------*/
  225.  default_file_attributes(save_current_file);
  226.  if (strcmp(dir_filename,sp_fname) == 0)
  227.     CURRENT_FILE->pseudo_file = PSEUDO_DIR;
  228.  if (strcmp(rexxoutname,sp_fname) == 0)
  229.     CURRENT_FILE->pseudo_file = PSEUDO_REXX;
  230. /*---------------------------------------------------------------------*/
  231. /* Copy the filename and path strings split up at the start of the     */
  232. /* function.                                                           */
  233. /*---------------------------------------------------------------------*/
  234.  if ((CURRENT_FILE->fname = (CHARTYPE *)(*the_malloc)(strlen(sp_fname)+1)) == NULL)
  235.    {
  236.     free_view_memory();
  237.     display_error(30,(CHARTYPE *)"",FALSE);
  238. #ifdef TRACE
  239.     trace_return();
  240. #endif
  241.     return(RC_OUT_OF_MEMORY);
  242.    }
  243.  if ((CURRENT_FILE->fpath = (CHARTYPE *)(*the_malloc)(strlen(sp_path)+1)) == NULL)
  244.    {
  245.     free_view_memory();
  246.     display_error(30,(CHARTYPE *)"",FALSE);
  247. #ifdef TRACE
  248.     trace_return();
  249. #endif
  250.     return(RC_OUT_OF_MEMORY);
  251.    }
  252.  strcpy(CURRENT_FILE->fname,sp_fname);
  253.  strcpy(CURRENT_FILE->fpath,sp_path);
  254.  
  255.  strcpy(work_filename,sp_path);
  256.  strcat(work_filename,sp_fname);
  257. /*---------------------------------------------------------------------*/
  258. /* If the file is not readable, then display error.                    */
  259. /*---------------------------------------------------------------------*/
  260.  if (!file_readable(work_filename))
  261.    {
  262.     display_error(8,work_filename,FALSE);
  263.     free_view_memory();
  264. #ifdef TRACE
  265.     trace_return();
  266. #endif
  267.     return(RC_ACCESS_DENIED);
  268.    }
  269.  
  270.  if (file_exists(work_filename))
  271.    {
  272.     if (file_writable(work_filename))
  273.        file_disposition = FILE_NORMAL;
  274.     else
  275.       {
  276.        file_disposition = FILE_READONLY;
  277.        if (!in_profile)
  278.           display_error(0,(CHARTYPE *)"File is read-only...",FALSE);
  279.       }
  280.     if ((CURRENT_FILE->fp = fopen(work_filename,"r")) == NULL)
  281.       {
  282. #ifdef TRACE
  283.        trace_return();
  284. #endif
  285.        return(RC_ACCESS_DENIED);
  286.       }
  287.    }
  288.  else
  289.    {
  290.     file_disposition = FILE_NEW;
  291.     if (!in_profile)
  292.        display_error(0,(CHARTYPE *)"New file...",TRUE);
  293.    }
  294. /*---------------------------------------------------------------------*/
  295. /* first_line is set to "Top of File"                                  */
  296. /*---------------------------------------------------------------------*/
  297.  if ((CURRENT_FILE->first_line = add_line(CURRENT_FILE->first_line,NULL,TOP_OF_FILE,
  298.      strlen(TOP_OF_FILE),0)) == NULL)
  299.    {
  300.     free_view_memory();
  301. #ifdef TRACE
  302.     trace_return();
  303. #endif
  304.     return(RC_OUT_OF_MEMORY);
  305.    }
  306.  
  307.  curr = CURRENT_FILE->first_line;
  308. /*---------------------------------------------------------------------*/
  309. /* Read in the existing file...                                        */
  310. /*---------------------------------------------------------------------*/
  311.  CURRENT_FILE->number_lines = 0L;
  312.  if (file_disposition != FILE_NEW)
  313.    {
  314.     stat(work_filename,&stat_buf);
  315.     CURRENT_FILE->fmode = stat_buf.st_mode;
  316.     if ((curr = read_file(CURRENT_FILE->fp,curr,work_filename)) == NULL)
  317.       {
  318.        free_view_memory();
  319. #ifdef TRACE
  320.        trace_return();
  321. #endif
  322.        return(RC_ACCESS_DENIED);
  323.       }
  324.    }
  325.  else
  326.     CURRENT_FILE->fmode = FMODE;
  327. /*---------------------------------------------------------------------*/
  328. /* last line is set to "Bottom of File"                                */
  329. /*---------------------------------------------------------------------*/
  330.  if ((CURRENT_FILE->last_line = add_line(CURRENT_FILE->first_line,curr,BOTTOM_OF_FILE,
  331.      strlen(BOTTOM_OF_FILE),0)) == NULL)
  332.    {
  333.     free_view_memory();
  334. #ifdef TRACE
  335.     trace_return();
  336. #endif
  337.     return(RC_OUT_OF_MEMORY);
  338.    }
  339.  
  340.  if (file_disposition != FILE_NEW)
  341.     fclose(CURRENT_FILE->fp);
  342.  
  343. #ifdef TRACE
  344.  trace_return();
  345. #endif
  346.  return(RC_OK);
  347. }
  348. #ifndef MSWIN
  349. /***********************************************************************/
  350. #ifdef PROTO
  351. LINE *read_file(FILE *fp,LINE *curr,CHARTYPE *filename)
  352. #else
  353. LINE *read_file(fp,curr,filename)
  354. FILE *fp;
  355. LINE *curr;
  356. CHARTYPE *filename;
  357. #endif
  358. /***********************************************************************/
  359. {
  360. /*-------------------------- external data ----------------------------*/
  361.  extern CHARTYPE TABI_ONx;
  362.  extern CHARTYPE TABI_Nx;
  363.  extern CHARTYPE *rec;
  364. /*--------------------------- local data ------------------------------*/
  365.  register unsigned short i=0;
  366.  short ch=0;
  367.  LINE *temp=NULL;
  368. /*--------------------------- processing ------------------------------*/
  369. #ifdef TRACE
  370.  trace_function("file.c:    read_file");
  371. #endif
  372.  temp = curr;
  373.  memset(rec,' ',max_line_length);
  374.  i = 0;
  375.  while(1)
  376.   {
  377.    ch = fgetc(fp);
  378.    if (feof(fp))
  379.      {
  380.       if (i > 0)     /* line with no CR and/or CR/LF */
  381.         {
  382.          if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i,0)) == NULL)
  383.            {
  384. #ifdef TRACE
  385.             trace_return();
  386. #endif
  387.             return(NULL);
  388.            }
  389.          CURRENT_FILE->number_lines++;
  390.         }
  391.       break;
  392.      }
  393.    if (ch == '\t'&& TABI_ONx)
  394.      {
  395.       do
  396.        {
  397.         rec[i] = ' ';
  398.         i++;
  399.         if (i >= max_line_length)
  400.           {
  401.            sprintf(rec,"Line %d exceeds max. width of %d",CURRENT_FILE->number_lines+1,max_line_length);
  402.            display_error(29,rec,FALSE);
  403. #ifdef TRACE
  404.            trace_return();
  405. #endif
  406.            return(NULL);
  407.           }
  408.        }
  409.       while ((i % TABI_Nx) != 0);
  410.       continue;
  411.      }
  412.    if (ch == '\n')
  413.      {
  414.       rec[i] = '\0';
  415.       if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i,0)) == NULL)
  416.         {
  417. #ifdef TRACE
  418.          trace_return();
  419. #endif
  420.          return(NULL);
  421.         }
  422.       CURRENT_FILE->number_lines++;
  423.       i = 0;
  424.       memset(rec,' ',max_line_length);
  425.       continue;
  426.      }
  427.    if (ch == '\r')
  428.      {
  429.       rec[i] = ch;
  430.       i++;
  431.       ch = fgetc(fp);
  432.       if (feof(fp))
  433.          break;
  434.       if (ch == '\n')
  435.         {
  436.          --i;
  437.          rec[i] = '\0';
  438.          if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i,0)) == NULL)
  439.            {
  440. #ifdef TRACE
  441.             trace_return();
  442. #endif
  443.             return(NULL);
  444.            }
  445.          CURRENT_FILE->number_lines++;
  446.          i = 0;
  447.          memset(rec,' ',max_line_length);
  448.          continue;
  449.         }
  450.      }
  451.    rec[i] = ch;
  452.    i++;
  453.    if (i >= max_line_length)
  454.      {
  455.       sprintf(rec,"Line %d exceeds max. width of %d",CURRENT_FILE->number_lines+1,max_line_length);
  456.       display_error(29,rec,FALSE);
  457. #ifdef TRACE
  458.       trace_return();
  459. #endif
  460.       return(NULL);
  461.      }
  462.   }
  463. #ifdef TRACE
  464.  trace_return();
  465. #endif
  466.  return(temp);
  467. }
  468. #endif
  469. /***********************************************************************/
  470. #ifdef PROTO
  471. short save_file(FILE_DETAILS *cf,CHARTYPE *new_fname,bool force,LINETYPE in_lines,
  472.                 LINETYPE start_line,bool append,short start_col, short end_col,bool ignore_scope)
  473. #else
  474. short save_file(cf,new_fname,force,in_lines,start_line,append,start_col,end_col,ignore_scope)
  475. FILE_DETAILS *cf;
  476. CHARTYPE *new_fname;
  477. bool force,append;
  478. LINETYPE in_lines,start_line;
  479. short start_col,end_col;
  480. bool ignore_scope;
  481. #endif
  482. /***********************************************************************/
  483. {
  484. /*------------------------- external data -----------------------------*/
  485.  extern CHARTYPE sp_fname[MAX_FILE_NAME+1];
  486.  extern CHARTYPE sp_path[MAX_FILE_NAME+1];
  487. /*--------------------------- local data ------------------------------*/
  488.  CHARTYPE *bak_filename=NULL;
  489.  CHARTYPE *write_fname=NULL;
  490.  register short i=0;
  491.  LINETYPE j=0L;
  492.  LINETYPE num_lines=in_lines;
  493.  LINE *curr=NULL;
  494.  FILE *fp=NULL;
  495.  unsigned short col=0,newcol=0;
  496.  short off=0;
  497.  CHARTYPE c=0;
  498.  short rc=RC_OK;
  499.  bool same_file=TRUE;
  500.  short anerror=0;
  501. /*--------------------------- processing ------------------------------*/
  502. #ifdef TRACE
  503.  trace_function("file.c:    save_file");
  504. #endif
  505.  if ((write_fname = (CHARTYPE *)(*the_malloc)(MAX_FILE_NAME)) == NULL)
  506.    {
  507.     display_error(30,(CHARTYPE *)"",FALSE);
  508. #ifdef TRACE
  509.     trace_return();
  510. #endif
  511.     return(RC_OUT_OF_MEMORY);
  512.    }
  513. /*---------------------------------------------------------------------*/
  514. /* If a new filename is specified, use it as the old filename.         */
  515. /*---------------------------------------------------------------------*/
  516.  (void *)strtrans(new_fname,OSLASH,ISLASH);
  517.  if (strcmp(new_fname,"") != 0)                  /* new_fname supplied */
  518.    {
  519. /*---------------------------------------------------------------------*/
  520. /* Split the supplied new filename.                                    */
  521. /*---------------------------------------------------------------------*/
  522.     if ((rc = splitpath(new_fname)) != RC_OK)
  523.       {
  524.        display_error(10,new_fname,FALSE);
  525.        if (bak_filename != (CHARTYPE *)NULL)
  526.           (*the_free)(bak_filename);
  527.        if (write_fname != (CHARTYPE *)NULL)
  528.           (*the_free)(write_fname);
  529. #ifdef TRACE
  530.        trace_return();
  531. #endif
  532.        return(rc);
  533.       }
  534.     strcpy(write_fname,sp_path);
  535.     strcat(write_fname,sp_fname);
  536.     same_file = FALSE;
  537. /*---------------------------------------------------------------------*/
  538. /* Test to make sure that the write fname doesn't exist...             */
  539. /* ...unless we are forcing the write.                                 */
  540. /*---------------------------------------------------------------------*/
  541.     if ((!force) && file_exists(write_fname))
  542.       {
  543.        display_error(31,write_fname,FALSE);
  544.        if (bak_filename != (CHARTYPE *)NULL)
  545.           (*the_free)(bak_filename);
  546.        if (write_fname != (CHARTYPE *)NULL)
  547.           (*the_free)(write_fname);
  548. #ifdef TRACE
  549.        trace_return();
  550. #endif
  551.        return(RC_ACCESS_DENIED);
  552.       }
  553. /*---------------------------------------------------------------------*/
  554. /* Test to make sure that we can write the file.                       */
  555. /*---------------------------------------------------------------------*/
  556.     if (!file_writable(write_fname))
  557.       {
  558.        display_error(8,write_fname,FALSE);
  559.        if (bak_filename != (CHARTYPE *)NULL)
  560.           (*the_free)(bak_filename);
  561.        if (write_fname != (CHARTYPE *)NULL)
  562.           (*the_free)(write_fname);
  563. #ifdef TRACE
  564.        trace_return();
  565. #endif
  566.        return(RC_ACCESS_DENIED);
  567.       }
  568.    }
  569.  else
  570.    {
  571. /*---------------------------------------------------------------------*/
  572. /* We are using the same file name for the new file.                   */
  573. /* Create the name of the current file.                                */
  574. /*---------------------------------------------------------------------*/
  575.     strcpy(write_fname,cf->fpath);
  576.     strcat(write_fname,cf->fname);
  577. /*---------------------------------------------------------------------*/
  578. /* If the file exists, test to make sure we can write it and save a    */
  579. /* backup copy.                                                        */
  580. /*---------------------------------------------------------------------*/
  581.     if (file_exists(write_fname))
  582.       {
  583. /*---------------------------------------------------------------------*/
  584. /* Test to make sure that we can write the file.                       */
  585. /*---------------------------------------------------------------------*/
  586.        if (!file_writable(write_fname))
  587.          {
  588.           display_error(8,write_fname,FALSE);
  589.           if (bak_filename != (CHARTYPE *)NULL)
  590.              (*the_free)(bak_filename);
  591.           if (write_fname != (CHARTYPE *)NULL)
  592.              (*the_free)(write_fname);
  593. #ifdef TRACE
  594.           trace_return();
  595. #endif
  596.           return(RC_ACCESS_DENIED);
  597.          }
  598. /*---------------------------------------------------------------------*/
  599. /* Rename the current file to filename.bak.                            */
  600. /*---------------------------------------------------------------------*/
  601.        if (cf->backup != BACKUP_OFF)
  602.          {
  603.           if ((bak_filename =
  604.              (CHARTYPE *)(*the_malloc)(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
  605.             {
  606.              display_error(30,(CHARTYPE *)"",FALSE);
  607.              if (bak_filename != (CHARTYPE *)NULL)
  608.                 (*the_free)(bak_filename);
  609.              if (write_fname != (CHARTYPE *)NULL)
  610.                 (*the_free)(write_fname);
  611. #ifdef TRACE
  612.              trace_return();
  613. #endif
  614.              return(RC_OUT_OF_MEMORY);
  615.             }
  616.           new_filename(cf->fpath,cf->fname,bak_filename,(CHARTYPE *)".bak");
  617.           if (cf->fp != NULL)
  618.             {
  619.              remove_file(bak_filename);
  620.              if (rename(write_fname,bak_filename) != 0)
  621.                {
  622.                 display_error(8,write_fname,FALSE);
  623.                 if (bak_filename != (CHARTYPE *)NULL)
  624.                    (*the_free)(bak_filename);
  625.                 if (write_fname != (CHARTYPE *)NULL)
  626.                    (*the_free)(write_fname);
  627. #ifdef TRACE
  628.                 trace_return();
  629. #endif
  630.                 return(RC_ACCESS_DENIED);
  631.                }
  632.             }
  633.          }
  634.       }
  635.    }
  636. /*---------------------------------------------------------------------*/
  637. /* Open the file we are writing to...                                  */
  638. /*---------------------------------------------------------------------*/
  639.  if (append == TRUE)
  640.     fp = fopen(write_fname,"ab");
  641.  else
  642.     fp = fopen(write_fname,"wb");
  643.  if (fp == NULL)
  644.    {
  645.     display_error(8,(CHARTYPE *)"could not open for writing",FALSE);
  646.     if (bak_filename != (CHARTYPE *)NULL)
  647.        (*the_free)(bak_filename);
  648.     if (write_fname != (CHARTYPE *)NULL)
  649.        (*the_free)(write_fname);
  650. #ifdef TRACE
  651.     trace_return();
  652. #endif
  653.     return(RC_ACCESS_DENIED);
  654.    }
  655. /*---------------------------------------------------------------------*/
  656. /* Determine where to start writing from in the linked list.           */
  657. /*---------------------------------------------------------------------*/
  658.  curr = lll_find(cf->first_line,start_line);
  659. /*---------------------------------------------------------------------*/
  660. /* Now write out the contents of the file array to the new filename.   */
  661. /*---------------------------------------------------------------------*/
  662.  rc = RC_OK;
  663.  for (j=0L;j<num_lines && curr->next != NULL;j++)
  664.    {
  665.     if (start_line+j != 0L
  666.     && (ignore_scope
  667.     ||  in_scope(curr)
  668.     ||  CURRENT_VIEW->scope_all))
  669.       {
  670.        if (cf->tabsout_on)
  671.          {
  672.           col = 0;
  673.           off = start_col;
  674.           while (1)
  675.             {
  676.              newcol = col;
  677.              while ((c = next_char(curr,&off,end_col+1)) == ' ')
  678.                {
  679.                 newcol++;
  680.                 if ((newcol % cf->tabsout_num) == 0)
  681.                   {
  682.                    if ((rc = write_char((CHARTYPE)'\t',fp)) == RC_DISK_FULL)
  683.                       break;
  684.                    col = newcol;
  685.                   }
  686.                }
  687.              for (;col<newcol;col++)
  688.                  if ((rc = write_char((CHARTYPE)' ',fp)) == RC_DISK_FULL)
  689.                     break;
  690.              if (off == (-1))  /* end of line */
  691.                 break;
  692.              if ((rc = write_char((CHARTYPE)c,fp)) == RC_DISK_FULL)
  693.                 break;
  694.              col++;
  695.             }
  696.           if (rc) break;
  697.          }
  698.        else
  699.          {
  700.           for (i=start_col;i<min(curr->length,end_col+1);i++)
  701.               if ((rc = write_char((CHARTYPE)*(curr->line+i),fp)) == RC_DISK_FULL)
  702.                  break;
  703.          }
  704.        if (rc) break;
  705. /*       col = 0;*/
  706.        if (cf->eolout == EOLOUT_CRLF)
  707.          {
  708.           if ((rc = write_char((CHARTYPE)'\r',fp)) == RC_DISK_FULL)
  709.              break;
  710.          }
  711.        if ((rc = write_char((CHARTYPE)'\n',fp)) == RC_DISK_FULL)
  712.           break;
  713.       }
  714.     if (rc)
  715.        break;
  716.     curr = curr->next;
  717.    }
  718.  anerror = errno;
  719.  if (fflush(fp) == EOF)
  720.    {
  721.     rc = RC_DISK_FULL;
  722.     clearerr(fp);
  723.    }
  724.  if (fclose(fp) == EOF)
  725.     rc = RC_DISK_FULL;
  726.  if (rc)
  727.     clearerr(fp);
  728. /*---------------------------------------------------------------------*/
  729. /* If an error occurred in writing the file (usuallly a result of a    */
  730. /* disk full error), get the files back to the way they were before    */
  731. /* this attempt to write them.                                         */
  732. /*---------------------------------------------------------------------*/
  733.  if (rc)
  734.    {
  735.     /* remove 'new' file (the one that couldn't be written) */
  736.     remove_file(write_fname);
  737.     if (same_file)
  738.       {
  739.        if (rename(bak_filename,write_fname) != 0)
  740.          {
  741.           display_error(8,write_fname,FALSE);
  742.           if (bak_filename != (CHARTYPE *)NULL)
  743.              (*the_free)(bak_filename);
  744.           if (write_fname != (CHARTYPE *)NULL)
  745.              (*the_free)(write_fname);
  746. #ifdef TRACE
  747.           trace_return();
  748. #endif
  749.           return(RC_ACCESS_DENIED);
  750.          }
  751.       }
  752.    }
  753.  else
  754.    {
  755.     if (cf->fmode != 0)
  756.        chmod(write_fname,cf->fmode);
  757. /*---------------------------------------------------------------------*/
  758. /* If a backup file is not to be kept, remove the backup file provided */
  759. /* that there hasn't been a problem in writing the file.               */
  760. /*---------------------------------------------------------------------*/
  761.     if (cf->backup == BACKUP_TEMP)
  762.        remove_file(bak_filename);
  763. /*---------------------------------------------------------------------*/
  764. /* If a new filename was not supplied, free up temporary memory.       */
  765. /*---------------------------------------------------------------------*/
  766.    }
  767.  if (bak_filename != (CHARTYPE *)NULL)
  768.     (*the_free)(bak_filename);
  769.  if (write_fname != (CHARTYPE *)NULL)
  770.     (*the_free)(write_fname);
  771.  
  772. #ifdef TRACE
  773.  trace_return();
  774. #endif
  775.  return(rc);
  776. }
  777. /***********************************************************************/
  778. #ifdef PROTO
  779. short write_char(CHARTYPE chr,FILE *fp)
  780. #else
  781. short write_char(chr,fp)
  782. CHARTYPE chr;
  783. FILE *fp;
  784. #endif
  785. /***********************************************************************/
  786. {
  787. /*--------------------------- local data ------------------------------*/
  788. /*--------------------------- processing ------------------------------*/
  789.  if (fputc(chr,fp) == chr
  790.  && ferror(fp) == 0)
  791.     return(RC_OK);
  792.  clearerr(fp);
  793.  display_error(57,(CHARTYPE *)"",FALSE);
  794.  return(RC_DISK_FULL);
  795. }
  796. /***********************************************************************/
  797. #ifdef PROTO
  798. short increment_alt(FILE_DETAILS *cf)
  799. #else
  800. short increment_alt(cf)
  801. FILE_DETAILS *cf;
  802. #endif
  803. /***********************************************************************/
  804. {
  805. /*--------------------------- local data ------------------------------*/
  806.  CHARTYPE *aus_filename=NULL;
  807. /*--------------------------- processing ------------------------------*/
  808. #ifdef TRACE
  809.  trace_function("file.c:    increment_alt");
  810. #endif
  811.  cf->autosave_alt++;
  812.  cf->save_alt++;
  813. /*---------------------------------------------------------------------*/
  814. /* We can now test for autosave_alt exceeding the defined limit and    */
  815. /* carry out an autosave if necessary.                                 */
  816. /*---------------------------------------------------------------------*/
  817.  if (cf->autosave != 0
  818.  && cf->autosave_alt >= cf->autosave)
  819.    {
  820.     if ((aus_filename =
  821.        (CHARTYPE *)(*the_malloc)(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
  822.       {
  823.        display_error(30,(CHARTYPE *)"",FALSE);
  824. #ifdef TRACE
  825.        trace_return();
  826. #endif
  827.        return(RC_OUT_OF_MEMORY);
  828.       }
  829.     new_filename(cf->fpath,cf->fname,aus_filename,(CHARTYPE *)".aus");
  830.     save_file(cf,aus_filename,TRUE,cf->number_lines,1L,FALSE,0,max_line_length,TRUE);
  831.     (*the_free)(aus_filename);
  832.     cf->autosave_alt = 0;
  833.    }
  834. #ifdef TRACE
  835.  trace_return();
  836. #endif
  837.  return(RC_OK);
  838. }
  839. /***********************************************************************/
  840. #ifdef PROTO
  841. CHARTYPE *new_filename(CHARTYPE *ofp,CHARTYPE *ofn,
  842.                             CHARTYPE *nfn,CHARTYPE *ext)
  843. #else
  844. CHARTYPE *new_filename(ofp,ofn,nfn,ext)
  845. CHARTYPE *ofp,*ofn,*nfn,*ext;
  846. #endif
  847. /***********************************************************************/
  848. {
  849. /*--------------------------- local data ------------------------------*/
  850.  short rc=RC_OK;
  851. /*--------------------------- processing ------------------------------*/
  852. #ifdef TRACE
  853.  trace_function("file.c:    new_filename");
  854. #endif
  855.  strcpy(nfn,ofp);
  856.  strcat(nfn,ofn);
  857. #ifdef DOS
  858.  rc = strzeq(nfn,'.');
  859.  if (rc != (-1))
  860.     *(nfn+rc) = '\0';
  861. #endif
  862. #ifdef OS2
  863.  if (!LongFileNames(nfn)) /* returns TRUE if HPFS filesystem */
  864.    {
  865.     rc = strzreveq(nfn,'.');
  866.     if (rc != (-1))
  867.        *(nfn+rc) = '\0';
  868.    }
  869. #endif
  870.  strcat(nfn,ext);
  871. #ifdef TRACE
  872.  trace_return();
  873. #endif
  874.  return(nfn);
  875. }
  876. /***********************************************************************/
  877. #ifdef PROTO
  878. short remove_aus_file(FILE_DETAILS *cf)
  879. #else
  880. short remove_aus_file(cf)
  881. FILE_DETAILS *cf;
  882. #endif
  883. /***********************************************************************/
  884. {
  885. /*--------------------------- local data ------------------------------*/
  886.  CHARTYPE *aus_filename=NULL;
  887. /*--------------------------- processing ------------------------------*/
  888. #ifdef TRACE
  889.  trace_function("file.c:    remove_aus_file");
  890. #endif
  891.  if ((aus_filename =
  892.     (CHARTYPE *)(*the_malloc)(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
  893.    {
  894.     display_error(30,(CHARTYPE *)"",FALSE);
  895. #ifdef TRACE
  896.     trace_return();
  897. #endif
  898.     return(RC_OUT_OF_MEMORY);
  899.    }
  900.  new_filename(cf->fpath,cf->fname,aus_filename,(CHARTYPE *)".aus");
  901.  remove_file(aus_filename);
  902.  (*the_free)(aus_filename);
  903. #ifdef TRACE
  904.  trace_return();
  905. #endif
  906.  return(RC_OK);
  907. }
  908. /***********************************************************************/
  909. #ifdef PROTO
  910. short free_view_memory(void)
  911. #else
  912. short free_view_memory()
  913. #endif
  914. /***********************************************************************/
  915. {
  916. /*-------------------------- external data ----------------------------*/
  917.  extern bool curses_started;
  918.  extern CHARTYPE number_of_views;
  919.  extern CHARTYPE display_screens;
  920.  extern CHARTYPE number_of_files;
  921. /*--------------------------- local data ------------------------------*/
  922.  VIEW_DETAILS *save_current_view=NULL;
  923.  CHARTYPE save_current_screen=0;
  924.  short rc=RC_OK;
  925.  int y=0,x=0;
  926.  int scenario=0;
  927.  ROWTYPE save_cmd_line=0;
  928.  CHARTYPE save_prefix=0;
  929. /*--------------------------- processing ------------------------------*/
  930. #ifdef TRACE
  931.  trace_function("file.c:    free_view_memory");
  932. #endif
  933. /*---------------------------------------------------------------------*/
  934. /* Before freeing up anything, determine which scenario is current...  */
  935. /*---------------------------------------------------------------------*/
  936.  if (display_screens > 1)
  937.    {
  938.     if (CURRENT_SCREEN.screen_view->file_for_view
  939.         == OTHER_SCREEN.screen_view->file_for_view)
  940.       {
  941.        if (number_of_files > 1)
  942.           scenario = 2;
  943.        else
  944.           scenario = 3;
  945.       }
  946.     else
  947.        scenario = 4;
  948.    }
  949.  else
  950.    {
  951.     if (number_of_files > 1)
  952.        scenario = 1;
  953.     else
  954.        scenario = 0;
  955.    }
  956. /*---------------------------------------------------------------------*/
  957. /* Save details of the current view's prefix and cmd_line settings so  */
  958. /* that if the new view has different settings we can adjust the size  */
  959. /* and/or position of the new view's windows.                          */
  960. /*---------------------------------------------------------------------*/
  961.  save_prefix = CURRENT_VIEW->prefix;
  962.  save_cmd_line = CURRENT_VIEW->cmd_line;
  963. /*---------------------------------------------------------------------*/
  964. /* Free the view...                                                    */
  965. /*---------------------------------------------------------------------*/
  966.  if (--CURRENT_FILE->file_views == 0)
  967.     free_file_memory();
  968.  free_a_view();
  969.  
  970.  switch(scenario)
  971.    {
  972.     case 0:
  973.            /*----------------------------------------------------------*/
  974.            /* +---+---+                                                */
  975.            /* |   a   |                                                */
  976.            /* |       | --> exit                                       */
  977.            /* |qq     |                                                */
  978.            /* +---+---+                                                */
  979.            /* display_screens = 1 & number_of_files = 1 & same views   */
  980.            /* (scenario 0)                                             */
  981.            /*----------------------------------------------------------*/
  982.          break;
  983.     case 1:
  984.            /*----------------------------------------------------------*/
  985.            /* +---+---+     +---+---+                                  */
  986.            /* |   a   |  b  |   b   |                                  */
  987.            /* |       | --> |       |                                  */
  988.            /* |qq     |     |       |                                  */
  989.            /* +---+---+     +---+---+                                  */
  990.            /* display_screens = 1 & number_of_files > 1 & same views   */
  991.            /* (scenario 1)                                             */
  992.            /*----------------------------------------------------------*/
  993.          if ((save_prefix&PREFIX_LOCATION_MASK) != (CURRENT_VIEW->prefix&PREFIX_LOCATION_MASK)
  994.          ||  save_cmd_line != CURRENT_VIEW->cmd_line)
  995.            {
  996.             set_screen_defaults();
  997.             if (curses_started)
  998.               {
  999.                if (set_up_windows(current_screen) != RC_OK)
  1000.                  {
  1001. #ifdef TRACE
  1002.                   trace_return();
  1003. #endif
  1004.                   return(RC_OK);
  1005.                  }
  1006.               }
  1007.            }
  1008.          break;
  1009.     case 2:
  1010.            /*----------------------------------------------------------*/
  1011.            /* +---+---+     +---+---+       +---+---+     +---+---+    */
  1012.            /* | a | a |  b  | b | b |   or  | a | a | b c | b | b |    */
  1013.            /* |   |   | --> |   |   |       |   |   |     |   |   |    */
  1014.            /* |   |qq |     |   |   |       |   |qq |     |   |   |    */
  1015.            /* +---+---+     +---+---+       +---+---+     +---+---+    */
  1016.            /* display_screens > 1 & number_of_files > 1 & same views   */
  1017.            /* (scenario 2)                                             */
  1018.            /*----------------------------------------------------------*/
  1019.          free_file_memory();
  1020.          free_a_view();
  1021.          save_current_screen = current_screen;
  1022.          save_current_view = CURRENT_VIEW;
  1023.          current_screen = (current_screen==0)?1:0; /* make other screen current */
  1024.          if ((rc = defaults_for_other_files(TRUE)) != RC_OK)
  1025.            {
  1026. #ifdef TRACE
  1027.             trace_return();
  1028. #endif
  1029.             return(rc);
  1030.            }
  1031.          CURRENT_FILE = save_current_view->file_for_view;
  1032.          CURRENT_FILE->file_views++;
  1033.          CURRENT_SCREEN.screen_view = CURRENT_VIEW;
  1034.          CURRENT_VIEW = save_current_view;
  1035.          current_screen = save_current_screen;
  1036.          set_screen_defaults();
  1037.          if ((rc = set_up_windows(current_screen)) != RC_OK)
  1038.            {
  1039. #ifdef TRACE
  1040.             trace_return();
  1041. #endif
  1042.             return(rc);
  1043.            }
  1044.          pre_process_line(OTHER_SCREEN.screen_view,OTHER_SCREEN.screen_view->focus_line);
  1045.          build_other_screen();
  1046.          display_other_screen();
  1047. #if 0
  1048.          pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  1049.          build_current_screen();
  1050.          display_current_screen();
  1051. #endif
  1052.          break;
  1053.     case 3:
  1054.            /*----------------------------------------------------------*/
  1055.            /* +---+---+                                                */
  1056.            /* | a | a |                                                */
  1057.            /* |   |   | --> exit                                       */
  1058.            /* |   |qq |                                                */
  1059.            /* +---+---+                                                */
  1060.            /* display_screens > 1 & number_of_files = 1 & same views   */
  1061.            /* (scenario 3)                                             */
  1062.            /*----------------------------------------------------------*/
  1063.          CURRENT_FILE->file_views--;
  1064.          free_file_memory();
  1065.          free_a_view();
  1066.          break;
  1067.     case 4:
  1068.            /*----------------------------------------------------------*/
  1069.            /* +---+---+     +---+---+       +---+---+     +---+---+    */
  1070.            /* | a | b |     | a | a |   or  | a | b |  c  | a | a |    */
  1071.            /* |   |   | --> |   |   |       |   |   |     |   |   |    */
  1072.            /* |   |qq |     |   |   |       |   |qq |     |   |   |    */
  1073.            /* +---+---+     +---+---+       +---+---+     +---+---+    */
  1074.            /* display_screens > 1 & number_of_files > 1 & diff views   */
  1075.            /* (scenario 4)                                             */
  1076.            /*----------------------------------------------------------*/
  1077.          if ((rc = defaults_for_other_files(FALSE)) != RC_OK)
  1078.            {
  1079. #ifdef TRACE
  1080.             trace_return();
  1081. #endif
  1082.             return(rc);
  1083.            }
  1084.          CURRENT_SCREEN.screen_view = CURRENT_VIEW;
  1085.          CURRENT_FILE = OTHER_SCREEN.screen_view->file_for_view;
  1086.          CURRENT_FILE->file_views++;
  1087.          set_screen_defaults();
  1088.          if ((rc = set_up_windows(current_screen)) != RC_OK)
  1089.            {
  1090. #ifdef TRACE
  1091.             trace_return();
  1092. #endif
  1093.             return(rc);
  1094.            }
  1095. /*         build_current_screen();
  1096.          display_current_screen();*/
  1097.          break;
  1098.     default:
  1099.          break;
  1100.    }
  1101.  
  1102.  if (number_of_views > 0)
  1103.    {
  1104.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  1105.     build_current_screen();
  1106.     display_current_screen();
  1107.     if (curses_started)
  1108.       {
  1109.        wmove(CURRENT_WINDOW_MAIN,CURRENT_VIEW->y[WINDOW_MAIN],CURRENT_VIEW->x[WINDOW_MAIN]);
  1110.        if (CURRENT_WINDOW_PREFIX != NULL)
  1111.           wmove(CURRENT_WINDOW_PREFIX,CURRENT_VIEW->y[WINDOW_PREFIX],CURRENT_VIEW->x[WINDOW_PREFIX]);
  1112.        getyx(CURRENT_WINDOW,y,x);
  1113.        wmove(CURRENT_WINDOW,y,x);
  1114.       }
  1115.    }
  1116. #ifdef TRACE
  1117.  trace_return();
  1118. #endif
  1119.  return(RC_OK);
  1120. }
  1121. /***********************************************************************/
  1122. #ifdef PROTO
  1123. void free_a_view(void)
  1124. #else
  1125. void free_a_view()
  1126. #endif
  1127. /***********************************************************************/
  1128. {
  1129. /*-------------------------- external data ----------------------------*/
  1130.  extern CHARTYPE number_of_views;
  1131.  extern VIEW_DETAILS *vd_first;
  1132.  extern bool curses_started;
  1133.  extern VIEW_DETAILS *vd_mark;
  1134. /*--------------------------- local data ------------------------------*/
  1135.  register int i;
  1136. /*--------------------------- processing ------------------------------*/
  1137. #ifdef TRACE
  1138.  trace_function("file.c:    free_a_view");
  1139. #endif
  1140. /*---------------------------------------------------------------------*/
  1141. /* If the marked block is within the current view, unset the variables.*/
  1142. /*---------------------------------------------------------------------*/
  1143.  if (MARK_VIEW == CURRENT_VIEW)
  1144.     MARK_VIEW = (VIEW_DETAILS *)NULL;
  1145.  CURRENT_VIEW = vll_del(&vd_first,NULL,CURRENT_VIEW,DIRECTION_FORWARD);
  1146.  CURRENT_SCREEN.screen_view = CURRENT_VIEW;
  1147.  
  1148.  number_of_views--;
  1149.  return;
  1150. }
  1151. /***********************************************************************/
  1152. #ifdef PROTO
  1153. short free_file_memory(void)
  1154. #else
  1155. short free_file_memory()
  1156. #endif
  1157. /***********************************************************************/
  1158. {
  1159. /*-------------------------- external data ----------------------------*/
  1160.  extern CHARTYPE number_of_files;
  1161. /*--------------------------- local data ------------------------------*/
  1162.  PPC *curr_ppc=NULL;
  1163. /*--------------------------- processing ------------------------------*/
  1164. #ifdef TRACE
  1165.  trace_function("file.c:    free_file_memory");
  1166. #endif
  1167. /*---------------------------------------------------------------------*/
  1168. /* If the file name is not NULL, free it...                            */
  1169. /*---------------------------------------------------------------------*/
  1170.  if (CURRENT_FILE->fname != NULL)
  1171.    {
  1172.     (*the_free)(CURRENT_FILE->fname);
  1173.     CURRENT_FILE->fname = (CHARTYPE *)NULL;
  1174.    }
  1175. /*---------------------------------------------------------------------*/
  1176. /* If the file path is not NULL, free it...                            */
  1177. /*---------------------------------------------------------------------*/
  1178.  if (CURRENT_FILE->fpath != NULL)
  1179.    {
  1180.     (*the_free)(CURRENT_FILE->fpath);
  1181.     CURRENT_FILE->fpath = (CHARTYPE *)NULL;
  1182.    }
  1183. /*---------------------------------------------------------------------*/
  1184. /* Free the linked list of all lines in the file...                    */
  1185. /*---------------------------------------------------------------------*/
  1186.  CURRENT_FILE->first_line = lll_free(CURRENT_FILE->first_line);
  1187. /*---------------------------------------------------------------------*/
  1188. /* Free the linked list of all pending prefix commands...              */
  1189. /*---------------------------------------------------------------------*/
  1190.  pll_free(CURRENT_FILE->first_ppc);
  1191. /*---------------------------------------------------------------------*/
  1192. /* Free the linked list of reserved lines...                           */
  1193. /*---------------------------------------------------------------------*/
  1194.  rll_free(CURRENT_FILE->first_reserved);
  1195. /*---------------------------------------------------------------------*/
  1196. /* Free the FILE_DETAILS structure...                                  */
  1197. /*---------------------------------------------------------------------*/
  1198.  if (CURRENT_FILE != NULL)
  1199.    {
  1200.     (*the_free)(CURRENT_FILE);
  1201.     CURRENT_FILE = (FILE_DETAILS *)NULL;
  1202.    }
  1203.  number_of_files--;
  1204. #ifdef TRACE
  1205.  trace_return();
  1206. #endif
  1207.  return(RC_OK);
  1208. }
  1209. /***********************************************************************/
  1210. #ifdef PROTO
  1211. short read_directory(void)
  1212. #else
  1213. short read_directory()
  1214. #endif
  1215. /***********************************************************************/
  1216. {
  1217. /*-------------------------- external data ----------------------------*/
  1218.  extern CHARTYPE dir_filename[10];
  1219.  extern CHARTYPE dir_path[MAX_FILE_NAME+1];
  1220.  extern CHARTYPE *temp_cmd;
  1221.  extern CHARTYPE dir_pathname[MAX_FILE_NAME+1];
  1222.  extern CHARTYPE sp_path[MAX_FILE_NAME+1];
  1223.  extern CHARTYPE sp_fname[MAX_FILE_NAME+1];
  1224. /*--------------------------- local data ------------------------------*/
  1225.  struct dirfile *dpfirst=NULL,*dplast=NULL,*dp;
  1226.  CHARTYPE str_attr[11];
  1227.  CHARTYPE str_date[10];
  1228.  CHARTYPE str_time[6];
  1229. #ifdef UNIX
  1230.  struct tm *timp;
  1231. #endif
  1232.  short rc=RC_OK;
  1233.  FILE *fp=NULL;
  1234. /*--------------------------- processing ------------------------------*/
  1235. #ifdef TRACE
  1236.  trace_function("file.c:    read_directory");
  1237. #endif
  1238. /*---------------------------------------------------------------------*/
  1239. /* Get all file info for the selected files into structure. If no file */
  1240. /* name specified, force it to '*'.                                    */
  1241. /*---------------------------------------------------------------------*/
  1242.  if (strcmp(sp_fname,"") == 0)
  1243.     rc = getfiles(sp_path,(CHARTYPE *)"*",&dpfirst,&dplast);
  1244.  else
  1245.     rc = getfiles(sp_path,sp_fname,&dpfirst,&dplast);
  1246.  if (rc != RC_OK)
  1247.    {
  1248.     display_error(rc,sp_path,FALSE);
  1249. #ifdef TRACE
  1250.     trace_return();
  1251. #endif
  1252.     return(RC_FILE_NOT_FOUND);
  1253.    }
  1254.  if (dpfirst == dplast)
  1255.    {
  1256.     display_error(9,sp_path,FALSE);
  1257. #ifdef TRACE
  1258.     trace_return();
  1259. #endif
  1260.     return(RC_FILE_NOT_FOUND);
  1261.    }
  1262. /*---------------------------------------------------------------------*/
  1263. /* dir_path is set up here so that subsequent sos_edit commands can use*/
  1264. /* the directory path as a prefix to the edit files filename.          */
  1265. /*---------------------------------------------------------------------*/
  1266.  strcpy(dir_path,sp_path);
  1267. /*---------------------------------------------------------------------*/
  1268. /* sort the array of file structures.                                  */
  1269. /*---------------------------------------------------------------------*/
  1270.  qsort(dpfirst,dplast - dpfirst,sizeof(struct dirfile),fcomp);
  1271. /*---------------------------------------------------------------------*/
  1272. /* open the DIR.DIR file for output, overwriting any previous data     */
  1273. /*---------------------------------------------------------------------*/
  1274.  strcpy(temp_cmd,dir_pathname);
  1275.  strcat(temp_cmd,dir_filename);
  1276.  if ((fp = fopen(temp_cmd,"w")) == NULL)
  1277.    {
  1278.     display_error(8,sp_path,FALSE);
  1279. #ifdef TRACE
  1280.     trace_return();
  1281. #endif
  1282.     return(RC_ACCESS_DENIED);
  1283.    }
  1284. /*---------------------------------------------------------------------*/
  1285. /* write out the formatted contents of the file structures.            */
  1286. /*---------------------------------------------------------------------*/
  1287.  for (dp=dpfirst;dp<dplast;dp++)
  1288.     {
  1289. #ifdef UNIX
  1290.      timp = localtime(&(dp->ftime));
  1291. #endif
  1292.      fprintf(fp,"%s ",file_attrs(dp->fattr,str_attr));
  1293.      fprintf(fp,"%8ld ",dp->fsize);
  1294.      fprintf(fp,"%s ",file_date(D_NAME,str_date));
  1295.      fprintf(fp,"%s ",file_time(T_NAME,str_time));
  1296.      fprintf(fp,"%s\n",dp->fname);
  1297.      (*the_free)(dp->fname);
  1298.     }
  1299.  (*the_free)(dpfirst);
  1300.  fclose(fp);
  1301.  
  1302. #ifdef TRACE
  1303.  trace_return();
  1304. #endif
  1305.  return(RC_OK);
  1306. }
  1307. /***********************************************************************/
  1308. #ifdef PROTO
  1309. VIEW_DETAILS *find_file(CHARTYPE *fp,CHARTYPE *fn)
  1310. #else
  1311. VIEW_DETAILS *find_file(fp,fn)
  1312. CHARTYPE *fp,*fn;
  1313. #endif
  1314. /***********************************************************************/
  1315. {
  1316. /*-------------------------- external data ----------------------------*/
  1317.  extern VIEW_DETAILS *vd_first;
  1318. /*--------------------------- local data ------------------------------*/
  1319.  VIEW_DETAILS *save_current_view=NULL,*found_file=NULL;
  1320. /*--------------------------- processing ------------------------------*/
  1321. #ifdef TRACE
  1322.  trace_function("file.c:    find_file");
  1323. #endif
  1324.  save_current_view = CURRENT_VIEW;
  1325.  CURRENT_VIEW = vd_first;
  1326.  while(CURRENT_VIEW != (VIEW_DETAILS *)NULL)
  1327.    {
  1328. #ifdef UNIX
  1329.     if (strcmp(CURRENT_FILE->fname,fn) == 0
  1330.     &&  strcmp(CURRENT_FILE->fpath,fp) == 0)
  1331. #else
  1332.     if (stricmp(CURRENT_FILE->fname,fn) == 0
  1333.     &&  stricmp(CURRENT_FILE->fpath,fp) == 0)
  1334. #endif
  1335.       {
  1336. #ifdef TRACE
  1337.        trace_return();
  1338. #endif
  1339.        found_file = CURRENT_VIEW;
  1340.        CURRENT_VIEW = save_current_view;
  1341.        return(found_file);
  1342.       }
  1343.     CURRENT_VIEW = CURRENT_VIEW->next;
  1344.    }
  1345. #ifdef TRACE
  1346.  trace_return();
  1347. #endif
  1348.  CURRENT_VIEW = save_current_view;
  1349.  return((VIEW_DETAILS *)NULL);
  1350. }
  1351. /***********************************************************************/
  1352. #ifdef PROTO
  1353. short execute_command_file(FILE *fp)
  1354. #else
  1355. short execute_command_file(fp)
  1356. FILE *fp;
  1357. #endif
  1358. /***********************************************************************/
  1359. {
  1360. /*-------------------------- external data ----------------------------*/
  1361.  extern CHARTYPE number_of_files;
  1362. /*--------------------------- local data ------------------------------*/
  1363.  register short i=0;
  1364.  CHARTYPE ch=0;
  1365.  short rc=RC_OK;
  1366.  CHARTYPE profile_command_line[MAX_LENGTH_OF_LINE];
  1367.  short line_number=0;
  1368. /*--------------------------- processing ------------------------------*/
  1369. #ifdef TRACE
  1370.  trace_function("file.c:    execute_command_file");
  1371. #endif
  1372.  
  1373.  memset(profile_command_line,' ',MAX_LENGTH_OF_LINE);
  1374.  i = 0;
  1375.  while(1)
  1376.   {
  1377.    ch = fgetc(fp);
  1378.    if (feof(fp))
  1379.       break;
  1380.    if (ch == '\n')
  1381.      {
  1382.       line_number++;
  1383.       profile_command_line[i] = '\0';
  1384.       rc = process_command_line(profile_command_line,line_number);
  1385.       if (rc == RC_SYSTEM_ERROR)
  1386.          break;
  1387.       if (number_of_files == 0)
  1388.          break;
  1389.       i = 0;
  1390.       memset(profile_command_line,' ',MAX_LENGTH_OF_LINE);
  1391.       continue;
  1392.      }
  1393.    if (ch == '\r')
  1394.      {
  1395.       profile_command_line[i] = ch;
  1396.       i++;
  1397.       ch = fgetc(fp);
  1398.       if (feof(fp))
  1399.          break;
  1400.       if (ch == '\n')
  1401.         {
  1402.          --i;
  1403.          line_number++;
  1404.          profile_command_line[i] = '\0';
  1405.          rc = process_command_line(profile_command_line,line_number);
  1406.          if (rc == RC_SYSTEM_ERROR)
  1407.             break;
  1408.          if (number_of_files == 0)
  1409.             break;
  1410.          i = 0;
  1411.          memset(profile_command_line,' ',MAX_LENGTH_OF_LINE);
  1412.          continue;
  1413.         }
  1414.      }
  1415.    profile_command_line[i] = ch;
  1416.    i++;
  1417.   }
  1418. #ifdef TRACE
  1419.  trace_return();
  1420. #endif
  1421.  return(rc);
  1422. }
  1423. /***********************************************************************/
  1424. #ifdef PROTO
  1425. short process_command_line(CHARTYPE *profile_command_line,short line_number)
  1426. #else
  1427. short process_command_line(profile_command_line,line_number)
  1428. CHARTYPE *profile_command_line;
  1429. short line_number;
  1430. #endif
  1431. /***********************************************************************/
  1432. {
  1433. /*--------------------------- local data ------------------------------*/
  1434.  short rc=RC_OK;
  1435.  short len=0;
  1436.  bool strip=FALSE;
  1437. /*--------------------------- processing ------------------------------*/
  1438. #ifdef TRACE
  1439.  trace_function("file.c:    process_command_line");
  1440. #endif
  1441. /*---------------------------------------------------------------------*/
  1442. /* If the first line of the macro file does not contains '/*NOREXX'    */
  1443. /* abort further processing of the macro file.                         */
  1444. /*---------------------------------------------------------------------*/
  1445.  if (memcmp(profile_command_line,"/*NOREXX*/",10) != 0
  1446.  && line_number == 1)
  1447.    {
  1448. #ifdef TRACE
  1449.     trace_return();
  1450. #endif
  1451.     return(RC_SYSTEM_ERROR);
  1452.    }
  1453. /*---------------------------------------------------------------------*/
  1454. /* If the line is a comment, return with RC_OK.                        */
  1455. /*---------------------------------------------------------------------*/
  1456.  if (memcmp(profile_command_line,"/*",2) == 0)    /* is a comment line */
  1457.    {
  1458. #ifdef TRACE
  1459.     trace_return();
  1460. #endif
  1461.     return(RC_OK);
  1462.    }
  1463. /*---------------------------------------------------------------------*/
  1464. /* If the line begins and ends with a quote, single or double, strip   */
  1465. /* the quotes.                                                         */
  1466. /*---------------------------------------------------------------------*/
  1467.  len = strlen(profile_command_line);
  1468.  if (*(profile_command_line) == '\''
  1469.  &&  *(profile_command_line+len-1) == '\'')
  1470.     strip = TRUE;
  1471.  if (*(profile_command_line) == '"'
  1472.  &&  *(profile_command_line+len-1) == '"')
  1473.     strip = TRUE;
  1474.  if (strip)
  1475.    {
  1476.     *(profile_command_line+len-1) = '\0';
  1477.     profile_command_line++;
  1478.    }
  1479.  rc = command_line(profile_command_line,COMMAND_ONLY_FALSE);
  1480.  
  1481. #ifdef TRACE
  1482.  trace_return();
  1483. #endif
  1484.  return(rc);
  1485. }
  1486.